{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "12058891",
   "metadata": {},
   "source": [
    "\n",
    "# 基于修改后的 MindQuantum 0.5.0 采用变分算法重构半导体双量子点单-三重态量子 S 门"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba85bf73",
   "metadata": {},
   "source": [
    "# 用 abs 的自定义 MQLayer, 初始化方式为全 1 初始化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "12e11ce8",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "error_min: 0.17104566026303392 error_now: 0.17104566026303392 train_num: 0\n",
      "error_min: 0.16994808961272834 error_now: 0.5010764044733427 train_num: 100\n",
      "error_min: 0.008915443238600718 error_now: 0.016614243041115917 train_num: 200\n",
      "error_min: 0.006274768164063693 error_now: 0.01835062147747024 train_num: 300\n",
      "error_min: 0.006274768164063693 error_now: 0.680852060466135 train_num: 400\n",
      "error_min: 0.006274768164063693 error_now: 0.8722385188240911 train_num: 500\n",
      "error_min: 0.006274768164063693 error_now: 0.7596734053135297 train_num: 600\n",
      "error_min: 0.006274768164063693 error_now: 0.7510881910531879 train_num: 700\n",
      "error_min: 0.006274768164063693 error_now: 0.0162246428619357 train_num: 800\n",
      "\n",
      "error_min: 9.882213643730431e-06 train_num: 871\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import sys\n",
    "from numpy import kron\n",
    "from mindquantum import *\n",
    "from scipy.linalg import expm\n",
    "import mindspore as ms\n",
    "from mindspore import ops\n",
    "ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "from mindspore.nn import Adam, TrainOneStepCell\n",
    "from mindspore import Tensor\n",
    "from mindspore.common.parameter import Parameter\n",
    "from mindspore.common.initializer import initializer  \n",
    "ms.set_seed(1)\n",
    "np.random.seed(1)\n",
    "\n",
    "train_x = np.load('./src/1_qubit_s_train_x.npy', allow_pickle=True)\n",
    "eval_x = np.load('./src/1_qubit_s_eval_x.npy', allow_pickle=True)\n",
    "train_y = np.load('./src/1_qubit_s_train_y.npy', allow_pickle=True)\n",
    "eval_y = np.load('./src/1_qubit_s_eval_y.npy', allow_pickle=True)\n",
    "\n",
    "s_x = X.matrix()\n",
    "s_z = Z.matrix()\n",
    "one = I.matrix()\n",
    "dt = np.pi/2\n",
    "\n",
    "def _matrix_0(coeff):\n",
    "    return expm(-1j*(coeff*s_z+s_x)*dt)\n",
    "\n",
    "def _diff_matrix_0(coeff):\n",
    "    return -1j*_matrix_0(coeff)@(s_z*dt)\n",
    "\n",
    "gate_0 = gene_univ_parameterized_gate('gete_0', _matrix_0, _diff_matrix_0)\n",
    "\n",
    "circ = Circuit()\n",
    "circ += gate_0('00').on(0)\n",
    "circ += gate_0('01').on(0)\n",
    "circ += gate_0('02').on(0)\n",
    "circ += gate_0('03').on(0)\n",
    "circ += gate_0('04').on(0)\n",
    "circ += gate_0('05').on(0)\n",
    "\n",
    "circ += gate_0('06').on(0)\n",
    "circ += gate_0('07').on(0)\n",
    "circ += gate_0('08').on(0)\n",
    "circ += gate_0('09').on(0)\n",
    "\n",
    "circ += gate_0('10').on(0)\n",
    "circ += gate_0('11').on(0)\n",
    "# circ += gate_0('12').on(0)\n",
    "# circ += gate_0('13').on(0)\n",
    "# circ += gate_0('14').on(0)\n",
    "# circ += gate_0('15').on(0)\n",
    "\n",
    "\n",
    "ham = Hamiltonian(QubitOperator('')) \n",
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "sim_left = Simulator('projectq',circ.n_qubits)\n",
    "grad_ops = sim.get_expectation_with_grad(ham,\n",
    "                                         circ,\n",
    "                                         circ_left=Circuit(),\n",
    "                                         simulator_left=sim_left,\n",
    "                                         ansatz_params_name=circ.params_name)\n",
    "lr = 0.05\n",
    "Quantum_net = MQLayer(grad_ops)\n",
    "opti = Adam(Quantum_net.trainable_params(), learning_rate=lr)  \n",
    "net = TrainOneStepCell(Quantum_net, opti)\n",
    "error_min = 1\n",
    "for j in range(len(train_x)):\n",
    "    net(Tensor(train_x[j]), Tensor(train_y[j]))\n",
    "    params = abs(Quantum_net.weight.asnumpy())\n",
    "    final_state = []\n",
    "    for k in range(100): # 100 个测试点\n",
    "        sim.reset()\n",
    "        sim.set_qs(eval_x[k])\n",
    "        sim.apply_circuit(circ, params)\n",
    "        final_state.append(sim.get_qs())\n",
    "    error = 1-np.real(np.min([np.abs(np.vdot(bra, ket)) for bra, ket in zip(np.array(final_state), eval_y)]))\n",
    "    error_min = min(error, error_min)\n",
    "    if j % 100 == 0:\n",
    "        print('error_min:', error_min, 'error_now:', error, 'train_num:', j)\n",
    "    if error_min < 1e-5:\n",
    "        break\n",
    "        \n",
    "print('\\nerror_min:', error_min, 'train_num:', j)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
